package com.zhoug.common.utils;

import android.content.Context;
import android.media.MediaMetadataRetriever;
import android.os.Build;
import android.os.Environment;

import com.zhoug.common.annotation.Filetype;
import com.zhoug.common.content.FileType;
import com.zhoug.common.prodivers.AppContextProvider;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 文件工具
 */
public class FileUtils {
    private static final String TAG = "FileUtils";
    /**
     * 手机存储的sdcard根目录
     */
    public static final String SDCARD_ROOT = "/storage/emulated/0";

    @Deprecated
    private static Context appContext;

    @Deprecated
    public static void init(Context appContext) {
        FileUtils.appContext = appContext;
    }

    @Deprecated
    public static Context getAppContext() {
        if (appContext == null) {
            synchronized (ContactsUtils.class) {
                if (appContext == null) {
                    appContext = AppContextProvider.getAppContext();
                }
            }
        }
        return appContext;
    }

    /**
     * 获取文件名(包括后缀名)
     *
     * @param file
     * @return
     */

    public static String getNameWithSuffix(File file) {
        return getName(file);
    }


    /**
     * 获取文件名(包括后缀名)
     *
     * @param path
     * @return
     */

    public static String getNameWithSuffix(String path) {
        return getName(path);
    }

    /**
     * 获取文件名(包括后缀名)
     *
     * @param file
     * @return
     */
    public static String getName(File file) {
        if (file == null) {
            return null;
        }
        return file.getName();
    }


    /**
     * 获取文件名(包括后缀名)
     *
     * @param path
     * @return
     */
    public static String getName(String path) {
        if (path == null || path.length() == 0) {
            return null;
        }
        return getName(new File(path));
    }


    /**
     * 获取文件名(不包括后缀)
     *
     * @param file
     * @return
     */
    public static String getNameWithOutSuffix(File file) {
        if (file == null) return null;
        //文件夹
        if (file.isDirectory()) {
            return file.getName();
        }
        String nameWithType = getName(file);
        if (nameWithType != null) {
            int endIndex = nameWithType.lastIndexOf(".");
            if (endIndex >= 0 && endIndex < nameWithType.length()) {
                return nameWithType.substring(0, endIndex);
            } else {
                return nameWithType;
            }
        } else {
            return null;
        }
    }


    /**
     * 获取文件名(不包括后缀)
     *
     * @param path
     * @return
     */

    public static String getNameWithOutSuffix(String path) {
        return path == null ? null : getNameWithOutSuffix(new File(path));
    }

    /**
     * 获取文件的后缀(doc,png...)
     *
     * @param path
     * @return
     */
    public static String getSuffix(String path) {
        return path == null ? null : getSuffix(new File(path));
    }


    /**
     * 获取文件的后缀
     *
     * @param file
     * @return
     */
    public static String getSuffix(File file) {
        if (file != null && file.isDirectory()) {
            return null;
        }
        String name = getName(file);
        if (name != null && name.length() > 0) {
            int endIndex = name.lastIndexOf(".");
            if (endIndex >= 0 && endIndex < name.length()) {
                return name.substring(endIndex + 1);
            }
        }
        return null;
    }


    /**
     * 获取外部储存公用目录
     *
     * @param type
     * @return
     */
    public static File getExternalStoragePublicDirectory(String type) {
        if (isSDCardExist()) {
            File publicDirectory = Environment.getExternalStoragePublicDirectory(type);
            if (publicDirectory != null) {
                if (!publicDirectory.exists()) {
                    if (publicDirectory.mkdirs()) {
                        return publicDirectory;
                    }
                } else {
                    return publicDirectory;
                }
            }
        }
        return null;
    }

    /**
     * 获取外部储存根目录
     *
     * @return
     */
    public static File getExternalRoot() {
        return isSDCardExist() ? Environment.getExternalStorageDirectory() : null;
    }

    /**
     * 获取根目录:data/data/package/
     *
     * @param context
     * @return
     */
    public static String getAppDataRootDir(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return context.getDataDir().getAbsolutePath();
        }
        return context.getFilesDir().getParentFile().getAbsolutePath();
    }

    /**
     * 获取根目录下的子目录:data/data/package/dirName
     *
     * @param context
     * @param dirName 子目录名称
     * @return
     */
    public static String getAppDataDir(Context context, String dirName) {
        return new File(getAppDataRootDir(context), dirName).getAbsolutePath();
    }

    /**
     * 获取App外部储存根目录 android/data/package
     * @return
     */
    public static String getAppExternalRootDir(Context context) {
        File externalCacheDir = context.getExternalCacheDir();
        if (externalCacheDir != null) {
            return externalCacheDir.getParentFile().getAbsolutePath();
        }
        return null;
    }


    /**
     * 获取App外部储存根目录的子目录 android/data/package/dirName
     * @return
     */
    public static String getAppExternalRootDir(Context context,String dirName) {
        return new File(getAppExternalRootDir(context), dirName).getAbsolutePath();
    }

    /**
     * 创建文件夹
     *
     * @param file
     * @return 是否创建成功
     */
    public static boolean createDirectory(File file) {
        if (file == null) {
            return false;
        }
        if (!file.exists()) {
            return file.mkdirs();
        } else {
            return true;//文件夹存在
        }
    }

    /**
     * 创建文件夹
     *
     * @param absolutePath
     * @return 是否创建成功
     */
    public static boolean createDirectory(String absolutePath) {
        return absolutePath != null && createDirectory(new File(absolutePath));
    }

    /**
     * 创建文件
     *
     * @param file
     * @return 是否创建成功
     */
    public static boolean createFile(File file) {
        File parentFile = file.getParentFile();
        if (!parentFile.exists()) {
            boolean mkdirs = parentFile.mkdirs();
            if (mkdirs) {
                try {
                    return file.exists() || file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } else {
            try {
                return file.exists() || file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * 创建文件
     *
     * @param path
     * @return 是否创建成功
     */
    public static boolean createFile(String path) {
        return path != null && createFile(new File(path));
    }


    /**
     * sdcard是否存在
     *
     * @return
     */
    public static boolean isSDCardExist() {
        return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
    }




    /**
     * 获取外部储存根目录下的文件
     *
     * @param folder   文件夹
     * @param fileName 文件
     * @return
     */
    public static File getExternalFile(String folder, String fileName) {
        if (isSDCardExist()) {
            File root = getExternalRoot();
            File file1 = new File(root, folder);
            if (!file1.exists()) {
                boolean mkdirs = file1.mkdirs();
                if (mkdirs) {
                    return new File(file1, fileName);
                } else {
                    return null;
                }
            } else {
                return new File(file1, fileName);
            }
        } else {
            return null;
        }
    }

    /**
     * 获取外部储存根目录下目录路径,不存在则创建
     *
     * @param name
     * @return
     */
    public static String getExternalFolder(String name) {
        if (isSDCardExist()) {
            File root = getExternalRoot();
            File folder = new File(root, name);
            if (!folder.exists()) {
                if (folder.mkdirs()) {
                    return folder.getAbsolutePath();
                }
            } else {
                return folder.getAbsolutePath();
            }

        }
        return null;
    }


    /**
     * 获取外部储存根目录下的文件
     *
     * @param path 文件路径
     * @return
     */
    public static File getExternalFile(String path) {
        if (isSDCardExist()) {
            File root = getExternalRoot();
            File file = new File(root, path);
            if (!file.getParentFile().exists()) {
                boolean mkdirs = file.getParentFile().mkdirs();
                if (mkdirs) {
                    return file;
                }
            } else {
                return file;
            }
        }
        return null;
    }

    public static File getExternalPublicFolder(String type) {
        return getExternalStoragePublicDirectory(type);
    }

    /**
     * 获取外部缓存
     *
     * @param folder 缓存目录 为null时表示缓存根目录
     * @return
     */
    public static File getAppExternalCacheFolder(Context context, String folder) {
        File cacheDir = context.getExternalCacheDir();
        File file = cacheDir;
        if (folder != null) {
            file = new File(cacheDir, folder);
        }
        if (file != null) {
            if (!file.exists()) {
                if (file.mkdirs()) {
                    return file;
                }
            } else {
                return file;
            }
        }
        return null;
    }

    /**
     * 获取应用的外部私有存储指定类型的目录
     *
     * @param context
     * @param type
     * @return
     */
    public static File getAppExternalFilesDir(Context context, String type) {
        File externalFilesDir = context.getExternalFilesDir(type);
        if (createDirectory(externalFilesDir)) {
            return externalFilesDir;
        }
        return null;
    }


    /**
     * 获取应用内部缓存目录
     *
     * @param context
     * @return
     */
    public static File getCacheDir(Context context) {
        File folder = context.getCacheDir();
        if (createDirectory(folder)) {
            return folder;
        }
        return null;
    }

    /**
     * 获取应用内部缓存目录
     *
     * @param context
     * @return
     */
    public static File getCacheDir(Context context, String path) {
        File folder = context.getCacheDir();
        if (folder != null) {
            File result = new File(folder, path);
            if (createDirectory(result)) {
                return result;
            } else {
                return null;
            }
        }
        return null;
    }


    /**
     * 获取文件夹下面所有文件的大小
     *
     * @param file
     * @return
     */
    public static long getFileSize(File file) {
        if (!file.exists()) {
            return 0;
        }
        long size = 0;
        if (file.isFile()) {
            return file.length();
        } else {
            File[] files = file.listFiles();
            for (File file1 : files) {
                size += getFileSize(file1);
            }
        }
//        Log.d(TAG, "getFileSize: size="+size);
        return size;
    }


    /**
     * 把字节大小转化为 以B\K\M... 为单位
     *
     * @param size
     * @return
     */
    public static String getFormatFileSize(long size) {
//        Log.d(TAG, "getFormatSize: size="+size);
        double kb = size / 1024.0;
        if (kb < 1) {
            return size + "B";
        }

        double mb = kb / 1024.0;
        if (mb < 1) {
            BigDecimal result1 = new BigDecimal(Double.toString(kb));
            return result1.setScale(2, BigDecimal.ROUND_HALF_UP)
                    .toPlainString() + "K";
        }

        double gb = mb / 1024.0;
        if (gb < 1) {
            BigDecimal result2 = new BigDecimal(Double.toString(mb));
            return result2.setScale(2, BigDecimal.ROUND_HALF_UP)
                    .toPlainString() + "M";
        }

        double tb = gb / 1024.0;
        if (tb < 1) {
            BigDecimal result3 = new BigDecimal(Double.toString(gb));
            return result3.setScale(2, BigDecimal.ROUND_HALF_UP)
                    .toPlainString() + "GB";
        }
        BigDecimal result4 = new BigDecimal(tb);
        return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString()
                + "TB";
    }

    /**
     * 获取app外部和内部缓存大小
     *
     * @return
     */
    @Deprecated
    public static String getAppCacheSize() {
        return getAppCacheSize(getAppContext());
    }

    /**
     * 获取app外部和内部缓存大小
     *
     * @param context
     * @return
     */
    public static String getAppCacheSize(Context context) {
        long size = 0;
        //外部存储的缓存
        if (isSDCardExist()) {
            File externalCacheDir = context.getExternalCacheDir();
            if (externalCacheDir != null && externalCacheDir.exists()) {
                size += getFileSize(externalCacheDir);
            }
        }
        //内部存储的缓存
        File cacheDir = context.getCacheDir();
        if (cacheDir != null && cacheDir.exists()) {
            size += getFileSize(cacheDir);
        }
        return getFormatFileSize(size);

    }

    /**
     * 删除文件/或文件夹下所有文件
     *
     * @param file
     */
    public static boolean deleteFile(File file) {
        if (!file.exists()) {
            return true;
        }
        if (file.isFile()) {
//            Log.d(TAG, "deleteFile: ");
            return file.delete();

        } else {
            File[] files = file.listFiles();
            for (File file1 : files) {
                deleteFile(file1);
            }
        }
        return true;
    }

    /**
     * 清除app的缓存[外部存储的缓存:context.getExternalCacheDir+内部存储的缓存:context.getCacheDir()]
     */
    @Deprecated
    public static void deleteAppCache() {
        deleteAppCache(getAppContext());
    }

    /**
     * 清除app的缓存[外部存储的缓存:context.getExternalCacheDir+内部存储的缓存:context.getCacheDir()]
     */
    public static void deleteAppCache(Context context) {
        //外部存储的缓存
        if (isSDCardExist()) {
            File externalCacheDir = context.getExternalCacheDir();
            if (externalCacheDir != null && externalCacheDir.exists()) {
                deleteFile(externalCacheDir);
            }
        }
        //内部存储的缓存
        File cacheDir = context.getCacheDir();
        if (cacheDir != null && cacheDir.exists()) {
            deleteFile(cacheDir);
        }
    }

    /**
     * 获取音视频文件的播放长度
     *
     * @param videoPath
     * @return
     */
    public static int getVideoDuration(String videoPath) {
        if (videoPath == null) {
            return 0;
        }
        int duration;
        try {
            MediaMetadataRetriever mmr = new MediaMetadataRetriever();
            mmr.setDataSource(videoPath);
            duration = Integer.parseInt(mmr.extractMetadata
                    (MediaMetadataRetriever.METADATA_KEY_DURATION));
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
        return duration;
    }


    /**
     * 递归获取文件目录下的指定后缀的文件
     *
     * @param folder 目录
     * @param suffix 后缀 (doc,png...)null表示所有文件
     * @return
     */
    public static List<String> findFiles(String folder, String... suffix) {
        if (folder == null) {
            return null;
        }
        //结果
        List<String> result = new ArrayList<>();
        File f = new File(folder);
        if (f.exists()) {
            File[] files = f.listFiles();
            if (files != null && files.length > 0) {
                for (File child : files) {
                    if (child.exists()) {
                        //是文件
                        if (child.isFile()) {
                            if (suffix != null) {
                                for (String s : suffix) {
                                    if (s.equals(getSuffix(child))) {
                                        result.add(child.getAbsolutePath());
                                    }
                                }
                            } else {
                                result.add(child.getAbsolutePath());
                            }
                        } else {
                            //是目录
                            List<String> paths = findFiles(child.getAbsolutePath(), suffix);
                            if (paths != null && paths.size() > 0) {
                                result.addAll(paths);
                            }
                        }
                    }
                }
            }
        }
        return result;
    }

    /**
     * 递归获取文件目录下的指定后缀的文件
     *
     * @param folder   文件目录
     * @param fileType {@link Filetype}
     * @return
     */
    public static List<String> findFiles(String folder, @Filetype int fileType) {
        if (folder == null) {
            return null;
        }
        //结果
        List<String> result = new ArrayList<>();
        File f = new File(folder);
        if (f.exists()) {
            File[] files = f.listFiles();
            if (files != null && files.length > 0) {
                for (File child : files) {
                    if (child.exists()) {
                        //是文件
                        if (child.isFile()) {
                            if (fileType != FileType.ALL) {
                                if (fileType == FileType.getType(child.getAbsolutePath())) {
                                    result.add(child.getAbsolutePath());
                                }
                            } else {
                                result.add(child.getAbsolutePath());
                            }
                        } else {
                            //是目录
                            List<String> paths = findFiles(child.getAbsolutePath(), fileType);
                            if (paths != null && paths.size() > 0) {
                                result.addAll(paths);
                            }
                        }
                    }
                }
            }
        }
        return result;
    }


}
